/*
===========================================================================
Copyright (C) 2013-2014 Avotu Briezhaudzetava

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.

===========================================================================
*/

#ifndef MAIN_H
#define MAIN_H

//
// defines
//
#define APPLET_DEBUG

//
// includes
//
#include <QObject>
#include <QStringList>
#include "common.h"
#ifdef APPLET_DEBUG
#include <QDebug>
#endif
#include "precursorentry.h"
#include "logentry.h"
#include <QComboBox>
#include "userentry.h"

//
// class: Main
//
class Main : public QObject {
    Q_OBJECT
    Q_CLASSINFO( "description", "Applet common structure" )
    Q_PROPERTY( bool initialized READ hasInitialized WRITE setInitialized )
    Q_PROPERTY( QString databaseDirectory READ databaseDirectory WRITE setDatabaseDirectory )
    Q_PROPERTY( QString databaseFilename READ databaseFilename WRITE setDatabaseFilename )
    Q_ENUMS( ErrorTypes )

public:
    // error types
    enum ErrorTypes {
        SoftError = 0,
        FatalError
    };

    // properties
    bool hasInitialized() const { return this->m_init; }
    QString databaseDirectory() const { return this->m_directory; }
    QString databaseFilename() const { return this->m_filename; }

    // precursors
    QList <PrecursorEntry *> precursorList;
    PrecursorEntry *precursorForTitle( const QString &title ) const;
    PrecursorEntry *precursorForId( int id ) const;

    // logs
    QList <LogEntry *> logList;
    QList <LogEntry *> logListFiltered;
    LogEntry *logForId( int id ) const;

    // TODO: also allow filtering by date, etc.
    void filterLogs( int precursorId );

    // remaining amount
    float remaining( int logId ) const;

    // units comboBox conversions
    static Common::Units indexToUnits( QComboBox *cPtr );
    static int unitsToIndex( QComboBox *cPtr, Common::Units units );
    static int getPrecision( Common::Units units );
    static float convert( float amount, Common::Units baseUnits, Common::Units units, float density );

    // users
    QList <UserEntry *> userList;
    UserEntry *userForId( int id ) const;
    UserEntry *userForName( const QString &name ) const;

public slots:
    void initialize();
    void print( const QString &msg );
    void error( ErrorTypes type, const QString &msg );
    void shutdown( bool ignoreDatabase = false );
    static void fillUnits( QComboBox *cPtr, bool isSolvent = false );

    // precursors
    void addPrecursor( const QString &title, const QString &lot, float baseAmount, Common::Units units = Common::Kilograms, bool solvent = false, float density = 1.0f );
    void removePrecursor( const QString &title );
    void loadPrecursors();

    // logs
    void addLog( int precursorId, int userId, float amount, const QString &date, const QString &purpose, Common::Units units = Common::Grams );
    void loadLogs();
    void removeLog( int id );

    // users
    void addUser( const QString &name, const QString &password = "", UserEntry::Flags flags = UserEntry::NoFlags );
    void removeUser( const QString &name );
    void loadUsers();

private slots:
    void setInitialized( bool init = true ) { this->m_init = init; }
    void setDatabaseDirectory( const QString &directory ) { this->m_directory = directory; }
    void setDatabaseFilename( const QString &filename ) { this->m_filename = filename; }
    void loadDatabase();
    void removeOrphanedLogs();

signals:
    void logListChanged();

private:
    bool m_init;
    QString m_directory;
    QString m_filename;
};

//
// externals
//
extern class Main m;

#endif // MAIN_H
